using System.IO;
using System.Linq;
using System.Collections.Generic;
using System;
using System.Xaml;

using MyUtils;
using MyUtils.UI;

using XTrace.Viewer.Properties;

namespace XTrace.Viewer.Filter
{
	class FilterStorage : Observable
	{
		public FilterModel GetAnything()
		{
			var first = Filters.FirstOrDefault(x => x.DisplayName == Settings.Default.LastFilterUsed);
			FilterModel result = null;
			if (first != null)
			{
				result = first;
			}
			else
			{
				first = Filters.FirstOrDefault();
				if (first != null)
				{
					result = first;
				}
			}
			if (result == null || result.DisplayName == Resources.FilterNew)
			{
				return Create();
			}
			return result;
		}

		FilterModel Create(string filterName = null)
		{
			var model = new FilterModel
			{
				FileName = Guid.NewGuid().ToString("N") + ".XTraceFilter",
				DisplayName = filterName ?? Resources.FilterMyFilter,
			};
			Save(model);
			return model;
		}

		private readonly string _filtersPath;

		public FilterStorage()
		{
			var appdata = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
			_filtersPath = Path.Combine(appdata, "XTrace", "Filters");
			Directory.CreateDirectory(_filtersPath);
		}

		public IEnumerable<FilterModel> Filters
		{
			get
			{
				var filters = Directory.GetFiles(_filtersPath, "*.XTraceFilter").Select(Load).OrderBy(x=>x.DisplayName).ToList();
				var filterNew = filters.FirstOrDefault(x => x.DisplayName == Resources.FilterNew);
				if (filterNew != null)
				{
					filters.Remove(filterNew);
					filters.Add(filterNew);
				}
				else
				{
					Create(Resources.FilterNew);
					return Filters;
				}

				return filters;
			}
		}

		public void Save(FilterModel model)
		{
			var path = Path.Combine(_filtersPath, model.FileName);
			XamlServices.Save(path, model);
			model.IsDirty = false;
			OnPropertyChanged("Filters");
		}

		private readonly WeakValueCache<string, FilterModel> _cache = new WeakValueCache<string, FilterModel>(StringComparer.OrdinalIgnoreCase);

		public FilterModel Load(string filePath)
		{
			return _cache[filePath, () =>
			{
				var model = (FilterModel)XamlServices.Load(filePath);
				model.FileName = filePath;
				model.Init();
				model.IsDirty = false;
				return model;
			}];
		}

		public void Delete(FilterModel filterModel)
		{
			MsgBox.CatchToMsgbox(() => File.Delete(filterModel.FileName));
			OnPropertyChanged("Filters");
		}
	}
}